from flask import Blueprint, jsonify, render_template, request, send_file
from pathlib import Path
import pandas as pd
import numpy as np
import sys
import os
from io import BytesIO

# 添加项目根目录到系统路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from transaction_type_analysis import analyze_transaction_types

# 创建蓝图
bank_flow_bak = Blueprint('bank_flow_bak', __name__, url_prefix='/bank-flow-bak')

# 配置数据文件路径
DATA_DIR = Path('data')
SOURCE_DIR = DATA_DIR / 'source'
OUTPUT_DIR = DATA_DIR / 'output'

# 确保目录存在
DATA_DIR.mkdir(parents=True, exist_ok=True)
SOURCE_DIR.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

def get_relatives_data(folder_name):
    """获取指定文件夹中的亲属关系数据"""
    try:
        # 从source目录读取亲属关系数据
        source_folder = SOURCE_DIR / folder_name
        file_path = source_folder / '亲属关系.xlsx'
        print(f"\n[DEBUG] 尝试读取亲属关系文件: {file_path}")
        
        if not file_path.exists():
            print(f"[DEBUG] 亲属关系文件不存在: {file_path}")
            return []
            
        # 读取Excel文件，跳过第一行，使用第二行作为列名
        print(f"[DEBUG] 开始读取Excel文件: {file_path}")
        df = pd.read_excel(file_path, header=1)
        print(f"[DEBUG] Excel文件读取成功，列名: {df.columns.tolist()}")
        
        # 只保留名称和关系列
        if '名称' in df.columns and '关系' in df.columns:
            print(f"[DEBUG] 找到名称和关系列")
            # 去除名称为空的行
            df = df[df['名称'].notna()]
            print(f"[DEBUG] 去除空名称后的行数: {len(df)}")
            # 去除重复值
            df = df.drop_duplicates(subset=['名称'])
            print(f"[DEBUG] 去除重复后的行数: {len(df)}")
            # 返回处理后的数据
            result = df[['名称', '关系']].values.tolist()
            print(f"[DEBUG] 返回的亲属数据数量: {len(result)}")
            print(f"[DEBUG] 亲属数据示例: {result[:3] if result else '无数据'}")
            return result
        else:
            print(f"[DEBUG] 未找到名称或关系列，现有列: {df.columns.tolist()}")
            return []
    except Exception as e:
        print(f"[DEBUG] 读取亲属关系文件出错 {file_path}: {str(e)}")
        import traceback
        traceback.print_exc()
        return []

@bank_flow_bak.route('/')
def index():
    """渲染银行流水分析页面"""
    return render_template('pages/bank_flow_bak.html', active_page='bank_flow_bak')

@bank_flow_bak.route('/load-data', methods=['GET'])
def load_data():
    """加载已有的分析结果数据"""
    try:
        print(f"\n[DEBUG] 开始加载数据")
        print(f"[DEBUG] 当前工作目录: {os.getcwd()}")
        print(f"[DEBUG] SOURCE_DIR: {SOURCE_DIR.absolute()}")
        print(f"[DEBUG] OUTPUT_DIR: {OUTPUT_DIR.absolute()}")
        
        if not OUTPUT_DIR.exists():
            return jsonify({
                'success': False,
                'error': '未找到数据目录'
            })

        all_data = []
        folders_data = []
        
        # 遍历output目录下的所有文件夹
        for folder in OUTPUT_DIR.iterdir():
            if folder.is_dir():
                folder_name = folder.name
                print(f"\n[DEBUG] 处理文件夹: {folder_name}")
                result_file = folder / "交易分类结果.xlsx"
                print(f"[DEBUG] 检查结果文件: {result_file}")
                
                if result_file.exists():
                    try:
                        # 读取Excel文件
                        df = pd.read_excel(result_file)
                        # 添加文件夹信息
                        df['文件夹'] = folder_name
                        all_data.append(df)
                        
                        # 获取亲属关系数据
                        print(f"[DEBUG] 开始获取亲属关系数据")
                        relatives = get_relatives_data(folder_name)
                        print(f"[DEBUG] 获取到亲属数量: {len(relatives)}")
                        
                        folders_data.append({
                            'name': folder_name,
                            'exists': True,
                            'relatives': relatives
                        })
                        print(f"[DEBUG] 已添加文件夹数据: {folder_name}, 亲属数量: {len(relatives)}")
                    except Exception as e:
                        print(f"处理文件 {result_file} 时出错: {str(e)}")
                        continue

        if not all_data:
            return jsonify({
                'success': False,
                'error': '未找到分析结果数据'
            })

        # 合并所有数据
        combined_df = pd.concat(all_data, ignore_index=True)
        
        # 处理数据中的特殊值（NaN等）
        data_list = []
        for _, row in combined_df.iterrows():
            record = {}
            for key, value in row.items():
                if pd.isna(value):
                    record[key] = None
                elif isinstance(value, (pd.Timestamp, pd.DatetimeTZDtype)):
                    record[key] = value.isoformat()
                elif isinstance(value, (float, int)):
                    # 对数值类型保留两位小数
                    record[key] = round(float(value), 2) if isinstance(value, float) else int(value)
                else:
                    record[key] = value
            data_list.append(record)
        
        print(f"[DEBUG] 返回数据: 文件夹数量={len(folders_data)}, 数据条数={len(data_list)}")
        return jsonify({
            'success': True,
            'data': data_list,
            'folders': folders_data,
            'total_records': len(data_list)
        })

    except Exception as e:
        print(f"[DEBUG] 加载数据时出错: {str(e)}")
        import traceback
        traceback.print_exc()
        return jsonify({
            'success': False,
            'error': f'加载数据时出错: {str(e)}'
        })

@bank_flow_bak.route('/analyze', methods=['POST'])
def analyze():
    """运行数据分析"""
    try:
        # 调用分析函数
        success = analyze_transaction_types()
        
        if success:
            return jsonify({
                'success': True,
                'message': '数据分析完成'
            })
        else:
            return jsonify({
                'success': False,
                'error': '数据分析失败'
            })
            
    except Exception as e:
        print(f"分析数据时出错: {str(e)}")
        return jsonify({
            'success': False,
            'error': f'分析数据时出错: {str(e)}'
        })

@bank_flow_bak.route('/filter-data', methods=['GET'])
def filter_data():
    """根据选中的文件夹、亲属和交易类型筛选数据"""
    try:
        print(f"\n[DEBUG] 开始筛选数据")
        
        # 获取筛选参数
        selected_folders = request.args.getlist('folders')
        selected_relatives = request.args.getlist('relatives')
        selected_types = request.args.getlist('types')  # 新增：获取选中的交易类型
        
        print(f"[DEBUG] 选中的文件夹: {selected_folders}")
        print(f"[DEBUG] 选中的亲属: {selected_relatives}")
        print(f"[DEBUG] 选中的交易类型: {selected_types}")  # 新增：打印选中的交易类型
        
        if not selected_folders:
            return jsonify({
                'success': False,
                'error': '请至少选择一个被审查人'
            })

        all_data = []
        
        # 遍历output目录下的选中的文件夹
        for folder_name in selected_folders:
            folder = OUTPUT_DIR / folder_name
            if folder.is_dir():
                result_file = folder / "交易分类结果.xlsx"
                print(f"[DEBUG] 检查结果文件: {result_file}")
                
                if result_file.exists():
                    try:
                        # 读取Excel文件
                        df = pd.read_excel(result_file)
                        # 添加文件夹信息
                        df['文件夹'] = folder_name
                        
                        # 如果选择了亲属，进行精确匹配筛选
                        if selected_relatives:
                            print(f"[DEBUG] 进行亲属筛选，名称列值: {df['名称'].unique().tolist()}")
                            df = df[df['名称'].isin(selected_relatives)]
                            print(f"[DEBUG] 亲属筛选后的数据行数: {len(df)}")

                        # 新增：如果选择了交易类型，进行精确匹配筛选
                        if selected_types:
                            print(f"[DEBUG] 进行交易类型筛选，类型列值: {df['类型'].unique().tolist()}")
                            df = df[df['类型'].isin(selected_types)]
                            print(f"[DEBUG] 交易类型筛选后的数据行数: {len(df)}")
                        
                        if len(df) > 0:
                            all_data.append(df)
                            print(f"[DEBUG] 成功读取文件: {result_file}, 数据行数: {len(df)}")
                        else:
                            print(f"[DEBUG] 文件 {result_file} 在筛选后没有匹配的数据")
                            
                    except Exception as e:
                        print(f"处理文件 {result_file} 时出错: {str(e)}")
                        continue

        if not all_data:
            return jsonify({
                'success': False,
                'error': '未找到匹配的数据'
            })

        # 合并所有数据
        combined_df = pd.concat(all_data, ignore_index=True)
        
        # 处理数据中的特殊值（NaN等）
        data_list = []
        for _, row in combined_df.iterrows():
            record = {}
            for key, value in row.items():
                if pd.isna(value):
                    record[key] = None
                elif isinstance(value, (pd.Timestamp, pd.DatetimeTZDtype)):
                    record[key] = value.isoformat()
                elif isinstance(value, (float, int)):
                    # 对数值类型保留两位小数
                    record[key] = round(float(value), 2) if isinstance(value, float) else int(value)
                else:
                    record[key] = value
            data_list.append(record)
        
        print(f"[DEBUG] 返回筛选后的数据: 数据条数={len(data_list)}")
        return jsonify({
            'success': True,
            'data': data_list,
            'total_records': len(data_list)
        })

    except Exception as e:
        print(f"[DEBUG] 筛选数据时出错: {str(e)}")
        import traceback
        traceback.print_exc()
        return jsonify({
            'success': False,
            'error': f'筛选数据时出错: {str(e)}'
        }) 

@bank_flow_bak.route('/download-excel')
def download_excel():
    """下载银行流水数据"""
    try:
        print(f"\n[DEBUG] 开始下载Excel数据")
        all_data = []
        
        # 获取筛选条件
        selected_folders = request.args.getlist('folders')  # 选择的文件夹
        selected_relatives = request.args.getlist('relatives')  # 选择的亲属
        selected_types = request.args.getlist('types')  # 选择的交易类型
        
        print(f"[DEBUG] 选中的文件夹: {selected_folders}")
        print(f"[DEBUG] 选中的亲属: {selected_relatives}")
        print(f"[DEBUG] 选中的交易类型: {selected_types}")
        
        if not selected_folders:
            print("[DEBUG] 未选择任何文件夹")
            return jsonify({'error': '请至少选择一个被审查人'}), 400

        # 遍历output目录下的选中的文件夹
        for folder_name in selected_folders:
            folder = OUTPUT_DIR / folder_name
            if folder.is_dir():
                result_file = folder / "交易分类结果.xlsx"
                print(f"[DEBUG] 检查结果文件: {result_file}")
                
                if result_file.exists():
                    try:
                        # 读取Excel文件
                        print(f"[DEBUG] 开始读取文件: {result_file}")
                        df = pd.read_excel(result_file)
                        print(f"[DEBUG] 成功读取文件，原始数据行数: {len(df)}")
                        print(f"[DEBUG] 文件列名: {df.columns.tolist()}")
                        
                        # 添加文件夹名称列
                        if '文件夹' not in df.columns:
                            df['文件夹'] = folder_name
                        
                        # 如果选择了亲属，进行精确匹配筛选
                        if selected_relatives:
                            print(f"[DEBUG] 进行亲属筛选，名称列值: {df['名称'].unique().tolist()}")
                            df = df[df['名称'].isin(selected_relatives)]
                            print(f"[DEBUG] 亲属筛选后的数据行数: {len(df)}")

                        # 如果选择了交易类型，进行精确匹配筛选
                        if selected_types:
                            print(f"[DEBUG] 进行交易类型筛选，类型列值: {df['类型'].unique().tolist()}")
                            df = df[df['类型'].isin(selected_types)]
                            print(f"[DEBUG] 交易类型筛选后的数据行数: {len(df)}")
                        
                        if len(df) > 0:
                            all_data.append(df)
                            print(f"[DEBUG] 成功添加文件数据: {result_file}, 数据行数: {len(df)}")
                        else:
                            print(f"[DEBUG] 文件 {result_file} 在筛选后没有匹配的数据")
                            
                    except Exception as e:
                        print(f"[DEBUG] 处理文件 {result_file} 时出错: {str(e)}")
                        import traceback
                        traceback.print_exc()
                        continue
                else:
                    print(f"[DEBUG] 文件不存在: {result_file}")

        if not all_data:
            print("[DEBUG] 没有找到任何匹配的数据")
            return jsonify({'error': '未找到匹配的数据'}), 404

        # 合并所有数据
        print("[DEBUG] 开始合并数据")
        combined_df = pd.concat(all_data, ignore_index=True)
        print(f"[DEBUG] 合并后的数据行数: {len(combined_df)}")
        print(f"[DEBUG] 合并后的列名: {combined_df.columns.tolist()}")
        
        # 获取选择的字段
        selected_fields = request.args.getlist('fields')
        print(f"[DEBUG] 选中的字段: {selected_fields}")
        
        if selected_fields:
            # 确保所有请求的字段都存在
            valid_fields = [field for field in selected_fields if field in combined_df.columns]
            if not valid_fields:
                print(f"[DEBUG] 没有找到有效的字段，请求的字段: {selected_fields}")
                return jsonify({'error': '没有找到有效的字段'}), 400
            print(f"[DEBUG] 有效的字段: {valid_fields}")
            combined_df = combined_df[valid_fields]
            print(f"[DEBUG] 选择字段后的数据行数: {len(combined_df)}")

        # 如果数据为空，返回错误
        if combined_df.empty:
            return jsonify({'error': '筛选后没有符合条件的数据'}), 400

        # 创建文件名
        filename = "交易分类结果.xlsx"
        
        # 使用BytesIO直接在内存中处理Excel文件
        excel_buffer = BytesIO()
        
        # 直接写入内存流
        with pd.ExcelWriter(excel_buffer, engine='openpyxl') as writer:
            combined_df.to_excel(writer, index=False, sheet_name='Sheet1')
        
        # 将指针移到开始位置
        excel_buffer.seek(0)
        
        return send_file(
            excel_buffer,
            as_attachment=True,
            download_name=filename,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )

    except Exception as e:
        print(f"[DEBUG] 下载文件时出错: {str(e)}")
        import traceback
        traceback.print_exc()
        return jsonify({
            'error': f'下载文件时出错: {str(e)}'
        }), 500